package cn.kkdlk.generate.dxf.util;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

public class FreemarkerSupport {

    private final Configuration configuration;

    private FreemarkerSupport() {
        configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);

        ClassTemplateLoader classTemplateLoader = new ClassTemplateLoader(ClassTemplateLoader.class, "/");
        TemplateLoader[] loaders = new TemplateLoader[]{classTemplateLoader};

        configuration.setTemplateLoader(new MultiTemplateLoader(loaders));
        configuration.setObjectWrapper(new BeansWrapperBuilder(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS).build());
    }

    public static FreemarkerSupport getInstance() {
        return SingletonHelper.instance;
    }

    public String processPath(String templatePath, Object object) {
        return processPath(templatePath, object, false);
    }

    private String processPath(String templatePath, Object object, boolean removeBlankLines) {
        Template template;
        try {
            template = configuration.getTemplate(templatePath);
        } catch (IOException e) {
            System.err.println(e.getMessage());
            throw new RuntimeException("failed to get template by (templatePath=" + templatePath + ")", e);
        }
        String templateStr = this.processTemplate(template, object);
        if (removeBlankLines) {
            templateStr = removeBlankLines(templateStr);
        }
        return templateStr;
    }

    private String processTemplate(Template template, Object object) {
        StringWriter writer = new StringWriter();
        try {
            if (template == null) {
                throw new RuntimeException("错误模板为空");
            }
            template.process(object, writer);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            throw new RuntimeException("failed to get template by (template=" + template + ")", e);
        }
        return writer.toString();
    }

    private String removeBlankLines(String src) {
        if (src != null && !src.trim().equals("")) {
            StringBuilder sb = new StringBuilder();
            String inputLine;
            String lineSepartor = System.getProperty("line.separator");
            try (BufferedReader bufferedReader = new BufferedReader(new StringReader(src))) {
                while ((inputLine = bufferedReader.readLine()) != null) {
                    if (inputLine.length() == 0 || inputLine.trim().length() == 0) {
                        continue;
                    }
                    sb.append(inputLine).append(lineSepartor);
                }
            } catch (IOException e) {
                System.err.println(e.getMessage());
                throw new RuntimeException("failed to read source string (src=" + src + ")", e);
            }
            return sb.toString();
        }
        return src;
    }

    private static class SingletonHelper {
        private static final FreemarkerSupport instance = new FreemarkerSupport();
    }
}
